package com.sub.structure.example;

import java.util.function.Consumer;

public class DynamicArray<E> {


    //数组初始长度
    private static final int INITIAL_CAPACITY = 16;


    //数组
    private Object[] array = {};

    //构造器:初始化数组
    public DynamicArray() {
        this.array = new Object[INITIAL_CAPACITY];
    }

    //当前元素个数
    private int size;

    /**
     * 获取当前元素个数
     *
     * @return 个数
     */
    public int size() {
        return size;
    }

    /**
     * 判断当前数组是否为空
     *
     * @return 是否为空
     */
    public boolean isEmpty() {
        return this.size == 0;
    }

    /**
     * 在指定位置添加元素
     *
     * @param index   添加位置
     * @param element 新元素
     */
    public void add(int index, E element) {

        if (index > size || index < 0) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }

        if (size >= array.length) {
            grow();
        }

        for (int i = size - 1; i >= index; i--) {
            array[i + 1] = array[i];
        }
        array[index] = element;
        size++;
    }

    /**
     * 在末尾添加元素
     *
     * @param element 新元素
     */
    public void add(E element) {
        add(size, element);
    }


    /**
     * 删除指定位置的元素
     *
     * @param index 删除位置
     * @return 删除的元素内容
     */
    public E remove(int index) {
        if (index >= size || index < 0) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        E result = (E) array[index];
        for (int i = index; i < size - 1; i++) {
            array[i] = array[i + 1];
        }
        size--;
        array[size] = null;
        return result;

    }


    /**
     * 数组扩容
     */
    private void grow() {
        int currentLength = array.length;
        Object[] newArray = new Object[currentLength * 2];
        for (int i = 0; i < size; i++) {
            newArray[i] = array[i];
        }
        array = newArray;
    }


    /**
     * 修改指定位置的元素
     *
     * @param index   指定位置
     * @param element 新元素内容
     * @return 旧元素内容
     */
    public E set(int index, E element) {
        if (index >= size || index < 0) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        E oldValue = (E) array[index];
        array[index] = element;
        return oldValue;
    }


    /**
     * 获取指定位置的元素
     *
     * @param index 位置
     * @return 指定位置元素
     */
    public E get(int index) {
        if (index >= size || index < 0) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        return (E) array[index];
    }


    /**
     * 遍历数组
     *
     * @param consumer 处理每个元素的函数
     */
    public void forEach(Consumer<E> consumer) {
        for (Object o : array) {
            consumer.accept((E) o);
        }
    }


    /**
     * 数组内容展示形式为[1,4,2,3,5]
     *
     * @return 数组元素列表
     */
    @Override
    public String toString() {

        if (size == 0)
            return "[]";

        StringBuilder sb = new StringBuilder();
        sb.append('[');
        for (int i = 0; i < size; i++) {
            sb.append((E) array[i]).append(",");
        }

        sb.replace(sb.length() - 1, sb.length(), "]");

        return sb.toString();
    }
}
